home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / od-pos / pos-rexx.c < prev    next >
C/C++ Source or Header  |  1998-01-20  |  16KB  |  522 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * pos-rexx.c
  5.   * 
  6.   * Copyright 1997 Samuel Devulder.
  7.   */
  8.  
  9. int  rexx_init(void);
  10. void rexx_exit(void);
  11. void rexx_led(int led, int on);
  12. void rexx_filename(int num, char *name);
  13. void rexx_handle_events(void);
  14.  
  15. int  rexx_init(void) {return 0;}
  16. void rexx_exit(void) {}
  17. void rexx_led(int led, int on) {}
  18. void rexx_filename(int num, char *name) {}
  19. void rexx_handle_events(void) {}
  20.  
  21. #if 0 /* nothing yet on pOS for rexx */
  22.  
  23. #include <proto/exec.h>
  24. #include <proto/alib.h>
  25. #include <proto/rexxsyslib.h>
  26. #include <proto/dos.h>
  27.  
  28. #include <rexx/storage.h>
  29. #include <rexx/errors.h>
  30.  
  31. /* this prevent a conflict between <rexx/rexxio.h> and <sys/dirent.h> */
  32. #undef DT_DIR 
  33.  
  34. /****************************************************************************/
  35.  
  36. #include "sysconfig.h"
  37. #include "sysdeps.h"
  38.  
  39. #include "uae.h"
  40. #include "config.h"
  41. #include "options.h"
  42. #include "../include/memory.h" /* or else gcc includes machdep/memory.h */
  43. #include "custom.h"
  44. #include "readcpu.h"
  45. #include "newcpu.h"
  46. #include "disk.h"
  47. #include "gui.h"
  48. #include "os.h"
  49.  
  50. #include <ctype.h>
  51.  
  52. /****************************************************************************/
  53.  
  54. #define UAE_PORTNAME    "UAE"
  55. #define RESULT_LEN      1024
  56. #define PORT_LEN        80
  57. #define CMD_LEN         1024
  58.  
  59. typedef struct
  60. {
  61.     char port[PORT_LEN];
  62.     char cmd_on[CMD_LEN];
  63.     char cmd_off[CMD_LEN];
  64. } gui_rexx_s;
  65.  
  66. enum {LED_POW, LED_DF0, LED_DF1, LED_DF2, LED_DF3,
  67.       NAME_DF0, NAME_DF1, NAME_DF2, NAME_DF3,
  68.       ON_EXIT,
  69.       GUI_REXX_MAX};
  70.  
  71. /****************************************************************************/
  72.  
  73. int  rexx_init(void);
  74. void rexx_exit(void);
  75. void rexx_led(int led, int on);
  76. void rexx_filename(int num, char *name);
  77. void rexx_handle_events(void);
  78.  
  79. /****************************************************************************/
  80.  
  81. struct /*RxsLib*/ Library
  82.                         *RexxSysBase;
  83. static struct MsgPort   *ARexxPort;
  84. static gui_rexx_s        gui_rexx[GUI_REXX_MAX];
  85. static char              RESULT[RESULT_LEN];
  86. static int               led_state[5];
  87.  
  88. static int   ADDRESS(char *hostname, char *cmd);
  89. static int   matchstr(char **line,char *pat);
  90. static void  extractstr(char **line, char *result, int len);
  91. static int   matchnum(char **line);
  92.  
  93. /****************************************************************************/
  94.  
  95. extern int quit_program;                                 /* ami-gui.c */
  96. extern void activate_debugger(void);                     /* debug.c */
  97. extern char *to_unix_path(char *s);                      /* ami-disk.c */
  98. extern char *from_unix_path(char *s);                    /* ami-disk.c */
  99.  
  100. /****************************************************************************/
  101.  
  102. int rexx_init(void)
  103. {
  104.     quit_program = 0;
  105.     RexxSysBase = (void*)OpenLibrary("rexxsyslib.library",0L);
  106.     if(!RexxSysBase) {
  107.         fprintf(stderr, "Can't find rexxsyslib.library!\n");
  108.         return 1;
  109.     }
  110.     if(FindPort(UAE_PORTNAME)) {
  111.         fprintf(stderr, "Port \"%s\" already exists!\n",UAE_PORTNAME);
  112.         return 1;    
  113.     }
  114.     ARexxPort = CreatePort(UAE_PORTNAME,0);
  115.     if(!ARexxPort) {
  116.         fprintf(stderr, "Failed to open AREXX port \"%s\"!\n",UAE_PORTNAME);
  117.         return 1;
  118.     }
  119.     fprintf(stderr,"Rexx port \"%s\" installed.\n", UAE_PORTNAME);
  120.     rexx_handle_events();
  121.     return 0;
  122. }
  123.  
  124. /****************************************************************************/
  125.  
  126. void rexx_exit(void)
  127. {
  128.     if(ARexxPort) {
  129.         struct RexxMsg *msg;
  130.         gui_rexx_s *gui = &gui_rexx[ON_EXIT];
  131.  
  132.         if(gui->port[0] && gui->cmd_on[0]) {
  133.             if(ADDRESS(gui->port, gui->cmd_on) != RC_OK) {
  134.                 fprintf(stderr,"%s:%s:%s\n", gui->port,
  135.                                              gui->cmd_on,
  136.                                              RESULT);
  137.             }
  138.             gui->port[0] = '\0';
  139.          }
  140.         Forbid();
  141.         while((msg = (struct RexxMsg*)GetMsg(ARexxPort))) {
  142.            msg->rm_Result1 = RC_ERROR;
  143.            msg->rm_Result2 = NULL;
  144.            ReplyMsg((void*)msg);
  145.         }
  146.         DeletePort(ARexxPort);
  147.         Permit();
  148.         ARexxPort = NULL;
  149.     }
  150.     if(RexxSysBase) {
  151.         CloseLibrary((void*)RexxSysBase);
  152.         RexxSysBase = NULL;
  153.     }
  154. }
  155.  
  156. /****************************************************************************/
  157.  
  158. static int EJECT(char *line)
  159. {
  160.     int drive = matchnum(&line);
  161.     if(drive<0 || drive>3) return RC_WARN;
  162.     disk_eject(drive);
  163.     sprintf(RESULT,"Drive %d ejected",drive);
  164.     return RC_OK;
  165. }
  166.  
  167. /****************************************************************************/
  168.  
  169. static int INSERT(char *line)
  170. {
  171.     int drive = matchnum(&line);
  172.     if(drive<0 || drive>3) return RC_WARN;
  173.     if(disk_empty(drive)) {
  174.         char buff[256];
  175.         char *name;
  176.         extractstr(&line, buff, 256);
  177.         name = to_unix_path(buff);
  178.         disk_insert(drive, name);
  179.         free(name);
  180.     } else {
  181.         sprintf(RESULT,"Drive %d not empty!",drive);
  182.         return RC_WARN;
  183.     }
  184.     return RC_OK;
  185. }
  186.  
  187. /****************************************************************************/
  188.  
  189. static void QUIT(void)
  190. {
  191.     broken_in = 1;
  192.     regs.spcflags |= SPCFLAG_BRK;
  193.     quit_program = 1;
  194. }
  195.  
  196. /****************************************************************************/
  197.  
  198. static int QUERY(char *line)
  199. {
  200.     char *res = NULL;
  201.     int   alc = 0;
  202.  
  203.     if     (matchstr(&line, "LED_POW"))  res = led_state[0]?"1":"0";
  204.     else if(matchstr(&line, "LED_DF0"))  res = led_state[1]?"1":"0";
  205.     else if(matchstr(&line, "LED_DF1"))  res = led_state[2]?"1":"0";
  206.     else if(matchstr(&line, "LED_DF2"))  res = led_state[3]?"1":"0";
  207.     else if(matchstr(&line, "LED_DF3"))  res = led_state[4]?"1":"0";
  208.     else if(matchstr(&line, "NAME_DF0")) res = from_unix_path(df0), alc = 1;
  209.     else if(matchstr(&line, "NAME_DF1")) res = from_unix_path(df1), alc = 1;
  210.     else if(matchstr(&line, "NAME_DF2")) res = from_unix_path(df2), alc = 1;
  211.     else if(matchstr(&line, "NAME_DF3")) res = from_unix_path(df3), alc = 1;
  212.     else if(matchstr(&line, "FAKEJOYSTICK")) res = fake_joystick?"1":"0";
  213.     else if(matchstr(&line, "DISPLAY"))  res = inhibit_frame?"0":"1";
  214.     else if(matchstr(&line, "FRAMERATE")) {
  215.         sprintf(RESULT,"%d",framerate);
  216.         return RC_OK;
  217.     } else if(matchstr(&line, "SOUND")) {
  218.         sprintf(RESULT,"%d",sound_available?produce_sound:-1);
  219.         return RC_OK;
  220.     } 
  221.     else return RC_ERROR;
  222.  
  223.     if(res) {
  224.         strncpy(RESULT, res, RESULT_LEN);
  225.         if(alc) free(res);
  226.     }
  227.     return RC_OK;
  228. }
  229.  
  230. /****************************************************************************/
  231.  
  232. static int FEEDBACK(char *line)
  233. {
  234.     gui_rexx_s *gui = NULL;
  235.  
  236.     if     (matchstr(&line,"LED_POW"))  gui = &gui_rexx[LED_POW];
  237.     else if(matchstr(&line,"LED_DF0"))  gui = &gui_rexx[LED_DF0];
  238.     else if(matchstr(&line,"LED_DF1"))  gui = &gui_rexx[LED_DF1];
  239.     else if(matchstr(&line,"LED_DF2"))  gui = &gui_rexx[LED_DF2];
  240.     else if(matchstr(&line,"LED_DF3"))  gui = &gui_rexx[LED_DF3];
  241.     else if(matchstr(&line,"NAME_DF0")) gui = &gui_rexx[NAME_DF0];
  242.     else if(matchstr(&line,"NAME_DF1")) gui = &gui_rexx[NAME_DF1];
  243.     else if(matchstr(&line,"NAME_DF2")) gui = &gui_rexx[NAME_DF2];
  244.     else if(matchstr(&line,"NAME_DF3")) gui = &gui_rexx[NAME_DF3];
  245.     else if(matchstr(&line,"ON_EXIT"))  gui = &gui_rexx[ON_EXIT];
  246.     else return RC_ERROR;
  247.  
  248.     while(1) {
  249.         if(matchstr(&line, "ADDRESS") ||
  250.            matchstr(&line, "PORT")) {
  251.             extractstr(&line, gui->port, PORT_LEN);
  252.         } else if(matchstr(&line,"COMMAND") ||
  253.                   matchstr(&line,"CMD") ||
  254.                   matchstr(&line,"CMD_ON")) {
  255.             extractstr(&line, gui->cmd_on,  CMD_LEN);
  256.         } else if(matchstr(&line,"CMD_OFF")) {
  257.             extractstr(&line, gui->cmd_off, CMD_LEN);
  258.         } else break;
  259.     }
  260.     return RC_OK;
  261. }
  262.  
  263. /****************************************************************************/
  264.  
  265. static int VERSION(char *line)
  266. {
  267.     if(matchstr(&line,"STRING")) {
  268.         sprintf(RESULT,
  269.                 "UAE-%d.%d.%d © by Bernd Schmidt & contributors, "
  270.                 "Amiga Port by Samuel Devulder.",
  271.                 (version / 100) % 10, (version / 10) % 10, version % 10);
  272.     } else if(matchstr(&line,"NUM")) {
  273.         sprintf(RESULT,"%d",version);
  274.     } else if(matchstr(&line,"AUTHOR")) {
  275.         sprintf(RESULT,"© by Bernd Schmidt & contributors");
  276.     } else if(matchstr(&line,"PORT")) {
  277.         sprintf(RESULT,"Amiga Port by Samuel Devulder");
  278.     } else return RC_ERROR;
  279.     return RC_OK;
  280. }
  281.  
  282. /****************************************************************************/
  283.  
  284. static int FRAMERATE(char *line)
  285. {
  286.     int num;
  287.     num = matchnum(&line);
  288.     if(num>=1 && num<=20) {
  289.         framerate = num;
  290.     } else {
  291.         sprintf(RESULT,"Invalid frame rate: %d\n", num);
  292.         return RC_WARN;
  293.     }
  294.     return RC_OK;
  295. }
  296.  
  297. /****************************************************************************/
  298.  
  299. static int FAKEJOYSTICK(char *line)
  300. {
  301.     if     (matchstr(&line,"ON"))     fake_joystick = 1;
  302.     else if(matchstr(&line,"OFF"))    fake_joystick = 0;
  303.     else if(matchstr(&line,"TOGGLE")) fake_joystick = fake_joystick?0:1;
  304.     else return RC_ERROR;
  305.     return RC_OK;
  306. }
  307.  
  308. /****************************************************************************/
  309.  
  310. static int DISPLAY(char *line)
  311. {
  312.     if     (matchstr(&line,"ON"))     inhibit_frame = 0;
  313.     else if(matchstr(&line,"OFF"))    inhibit_frame = 1;
  314.     else if(matchstr(&line,"TOGGLE")) inhibit_frame = inhibit_frame?0:1;
  315.     else return RC_ERROR;
  316.     return RC_OK;
  317. }
  318.  
  319. /****************************************************************************/
  320.  
  321. static int SOUND(char *line)
  322. {
  323.     if(!sound_available) {
  324.         sprintf(RESULT,"Sound not available!");
  325.         return RC_WARN;
  326.     }
  327.  
  328.     if     (matchstr(&line,"ON"))     produce_sound = 2;
  329.     else if(matchstr(&line,"OFF"))    produce_sound = 1;
  330.     else if(matchstr(&line,"BEST"))   produce_sound = 3;
  331.     else if(matchstr(&line,"TOGGLE")) produce_sound = produce_sound<=1?2:1;
  332.     else return RC_ERROR;
  333.     return RC_OK;
  334. }
  335.  
  336. /****************************************************************************/
  337.  
  338. static int process_cmd(char *line)
  339. {
  340.     RESULT[0] = '\0';
  341.     if     (matchstr(&line, "EJECT"))        return EJECT(line);
  342.     else if(matchstr(&line, "INSERT"))       return INSERT(line);
  343.     else if(matchstr(&line, "QUERY"))        return QUERY(line);
  344.     else if(matchstr(&line, "FEEDBACK"))     return FEEDBACK(line);
  345.     else if(matchstr(&line, "VERSION"))      return VERSION(line);
  346.     else if(matchstr(&line, "BYE"))          QUIT();
  347.     else if(matchstr(&line, "QUIT"))         QUIT();
  348.     else if(matchstr(&line, "DEBUG"))        activate_debugger();
  349.     else if(matchstr(&line, "RESET"))        m68k_reset();
  350.     else if(matchstr(&line, "DISPLAY"))      return DISPLAY(line);
  351.     else if(matchstr(&line, "FRAMERATE"))    return FRAMERATE(line);
  352.     else if(matchstr(&line, "FAKEJOYSTICK")) return FAKEJOYSTICK(line);
  353.     else if(matchstr(&line, "SOUND"))        return SOUND(line);
  354.     else return RC_ERROR;
  355.     return RC_OK;
  356. }
  357.  
  358. /****************************************************************************/
  359.  
  360. void rexx_handle_events(void)
  361. {
  362.     struct RexxMsg *msg;
  363.     while((msg = (struct RexxMsg*)GetMsg(ARexxPort))) {
  364.         if(!(msg->rm_Action & RXCOMM)) {
  365.             fprintf(stderr,"Unknown action '%08X' recieved!\n",
  366.                     msg->rm_Action);
  367.             continue;
  368.         }
  369.         msg->rm_Result1 = process_cmd(msg->rm_Args[0]);
  370.         msg->rm_Result2 = NULL;
  371.         if(msg->rm_Action & RXFF_RESULT) {
  372.             msg->rm_Result2 = (LONG)CreateArgstring(RESULT,strlen(RESULT));
  373.         }
  374.         ReplyMsg((void*)msg);
  375.     }
  376. }
  377.  
  378. /****************************************************************************/
  379.  
  380. void rexx_led(int led, int on)
  381. {
  382.     gui_rexx_s *gui = NULL;
  383.  
  384.     if(led < 0 || led > 4) return;
  385.     led_state[led] = on;
  386.  
  387.     if(led == 0) gui = &gui_rexx[LED_POW];
  388.     if(led == 1) gui = &gui_rexx[LED_DF0];
  389.     if(led == 2) gui = &gui_rexx[LED_DF1];
  390.     if(led == 3) gui = &gui_rexx[LED_DF2];
  391.     if(led == 4) gui = &gui_rexx[LED_DF3];
  392.  
  393.     if(gui->port[0] && gui->cmd_on[0] && gui->cmd_off[0]) {
  394.         if(ADDRESS(gui->port, on ? gui->cmd_on : gui->cmd_off) != RC_OK) {
  395.             fprintf(stderr,"%s:%s:%s\n", gui->port,
  396.                                          on ? gui->cmd_on : gui->cmd_off,
  397.                                          RESULT);
  398.         }
  399.     }
  400. }
  401.  
  402. /****************************************************************************/
  403.  
  404. void rexx_filename(int num, char *filename)
  405. {
  406.     gui_rexx_s *gui = NULL;
  407.     if(num < 0 || num > 3) return;
  408.     gui = &gui_rexx[NAME_DF0 + num];
  409.     if(gui->port[0] && gui->cmd_on[0]) {
  410.         char buf[CMD_LEN];
  411.         if(!(filename = from_unix_path(filename))) return;
  412.         sprintf(buf, gui->cmd_on, filename);
  413.         free(filename);
  414.         if(ADDRESS(gui->port, buf) != RC_OK) {
  415.             fprintf(stderr,"%s:%s:%s\n", gui->port, buf, RESULT);
  416.         }
  417.     }
  418. }
  419.  
  420. /****************************************************************************/
  421. /* send a message to an AREXX port.
  422.  */
  423. static int ADDRESS(char *hostname, char *cmd)
  424. {
  425.     struct MsgPort *RexxPort,
  426.                    *ReplyPort;
  427.     struct RexxMsg *HostMsg,
  428.                    *answer;
  429.     int result = RC_WARN;
  430.  
  431.     if(!stricmp(hostname, "COMMAND")) {
  432.         return SystemTagList(cmd,NULL);
  433.     }
  434.  
  435.     if((RexxPort = (void *)FindPort(hostname))) {
  436.         if((ReplyPort = (void *)CreateMsgPort())) {
  437.             if((HostMsg = CreateRexxMsg(ReplyPort, NULL, hostname))) {
  438.                 if((HostMsg->rm_Args[0] = CreateArgstring(cmd,strlen(cmd)))) {
  439.                     HostMsg->rm_Action  = RXCOMM | RXFF_RESULT;
  440.                     PutMsg(RexxPort, (void*)HostMsg);
  441.                     WaitPort(ReplyPort);
  442.                     while(!(answer = (void *)GetMsg(ReplyPort)));
  443.                     result = answer->rm_Result1;
  444.                     if(result == RC_OK) {
  445.                         if(answer->rm_Result2) {
  446.                         strncpy(RESULT,(char *)answer->rm_Result2,RESULT_LEN);
  447.                         DeleteArgstring((char *)answer->rm_Result2);
  448.                         } else RESULT[0] = '\0';
  449.                     }
  450.                     DeleteArgstring(HostMsg->rm_Args[0]);
  451.                 } else strcpy(RESULT, "Can't create argstring!");
  452.                 DeleteRexxMsg(HostMsg);
  453.             } else strcpy(RESULT, "Can't create rexx message!");
  454.             DeleteMsgPort(ReplyPort);
  455.         } else strcpy(RESULT, "Can't alloc reply port!");
  456.     } else sprintf(RESULT, "Port \"%s\" not found!",hostname);
  457.     return result;
  458. }
  459.  
  460. /****************************************************************************/
  461. /* argument parsing routines
  462.  */
  463. static int matchstr(char **line,char *pat)
  464. {
  465.     char *s = *line;
  466.     char match = 0;
  467.     while(isspace(*s)) ++s;
  468.     if(*s=='\"' || *s== '\'') match = *s++;
  469.     while(*s && (tolower(*s)==tolower(*pat)) && (!match || *s!=match)) {++s;++pat;}
  470.     if(match && *s==match && s[1]) ++s;
  471.     if(!*pat && (!*s || isspace(*s))) {
  472.         while(isspace(*s)) ++s;
  473.         *line = s;
  474.         return 1;
  475.     }
  476.     return 0;
  477. }
  478.  
  479. /****************************************************************************/
  480.  
  481. static void extractstr(char **line, char *result, int len)
  482. {
  483.     char *s    = *line;
  484.     char match = 0;
  485.  
  486.     while(isspace(*s)) ++s;
  487.  
  488.     if(*s=='\"' || *s=='\'') match = *s++;
  489.     while(*s && *s != match) {
  490.         if(*s == '\\' && (s[1] == '\'' || s[1] == '\"')) ++s;
  491.         if(len > 1) {*result++ = *s;--len;}
  492.         ++s;
  493.         if(!match && isspace(*s)) break;
  494.     }
  495.     if(match && *s == match) ++s;
  496.     while(isspace(*s)) ++s;
  497.  
  498.     *result  = '\0';
  499.     *line    = s;
  500. }
  501.  
  502. /****************************************************************************/
  503.  
  504. static int matchnum(char **line)
  505. {
  506.     char *s = *line, match = 0;
  507.     int sign = 1, num = 0;
  508.  
  509.     while(isspace(*s)) ++s;
  510.     if(*s=='\"' || *s=='\'') match = *s++;
  511.     if(*s=='-') {sign = -1;++s;}
  512.     if(*s=='+') ++s;
  513.     while(isspace(*s)) ++s;
  514.     while(*s>='0' && *s<='9') num = num*10 + (*s++ - '0');
  515.     if(match && *s==match && s[1]) ++s;
  516.     while(isspace(*s)) ++s;
  517.     *line = s;
  518.     return sign>0?num:-num;
  519. }
  520.  
  521. #endif
  522.